﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Plumber.Accounting.Forms;
using Plumber.Accounting.ModuleData;
using Plumber.Accounting.Reports.DataSet;
using Plumber.Masters.ModuleData;
using ApplicationLibrary.CounterManager;
using Plumber.Accounting.Library;

namespace Plumber.Accounting.Reports
{
    public partial class DebitsCredits : ApplicationLibrary.DBManager.ReportForm
    {
        private string Title                       = string.Empty;
        private DSDebitCredit dsDebitCredit = null;
        private DRMasters drMasters                = null;
        private DRMasterTypeByType drMastersByType = null;
        private DRMasterType drMasterType = null;
        private SqlABParameter pDocNo              = null;
        private SqlABParameter pType               = null;
        private SqlABParameter pCode               = null;
        private SqlABParameter pDate               = null;
        private SqlABCommand scc2                  = null;
        private string condominium;
        private EnumsManager<DebitCreditType> eDebitCreditType;
        private DRJournalEntry drJournalEntry = null;

        public DebitsCredits()
            : base(Properties.Resources.FN_MonthlySummary)
        {
            InitializeComponent();
        }

        protected override void OnBatchExecute(string reportName)
        {
            if (!LoadData())
            {
                MessageBox.Show(Properties.Resources.Msg_NoDataPeriod, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (eDebitCreditType.GetValue() == DebitCreditType.E_Debit)
                SetParameterValue("Title", string.Format("Debiti a Fornitore al {0}", ctbFromDate.Today.ToShortDateString()));
            else
                SetParameterValue("Title", string.Format("Crediti da Cliente al {0}", ctbFromDate.Today.ToShortDateString()));
            ShowReport(new RPTDebitCredit(), dsDebitCredit);

        }

        protected override void OnDisableControlsForRun()
        {
        }

        protected override void OnAttachData()
        {
            dsDebitCredit = new DSDebitCredit();
            drMasters = new DRMasters(false);
            drMastersByType = new DRMasterTypeByType();
            drMasterType = new DRMasterType(DRMasterType.Module.All);
            drJournalEntry = new DRJournalEntry(false);

            drMastersByType.Find(MasterTypes.E_Condominium);
            condominium = drMastersByType.GetValue<string>(PL_MasterType.Code);

            eDebitCreditType = new EnumsManager<DebitCreditType>(cbbRegister);

            ctbFromDate.Today = GlobalInfo.CurrentDate;
            AddClickableColumn(PL_JournalEntryDetail.JournalNo);
        }

        private bool LoadData()
        {
            dsDebitCredit.DebitCredit.Clear();

            QueryBuilder qb = new QueryBuilder(true);
            qb.Clear();
            qb.AddSelectAS(PL_JournalEntry.DocumentNo, "DocNo" );
            qb.AddSelect(PL_JournalEntry.DocumentDate);
            qb.AddSelect(PL_JournalEntry.JournalNo);
            qb.AddSelect(PL_JournalEntry.PostingDate);
            qb.AddSelect(PL_JournalEntry.Type);
            qb.AddSelect(PL_JournalEntry.Code);
            qb.AddSelect(PL_JournalEntry.Description);

            qb.AddSelectAll(PL_JournalEntryDetail.Name);
            qb.AddFrom(PL_JournalEntryDetail.Name);
            qb.AddJoin(QueryBuilder.JoinType.INNER, PL_JournalEntry.JournalNo, PL_JournalEntryDetail.JournalNo);

            qb.AddCompare<string>(PL_JournalEntryDetail.DocumentNo, "", "!=");

            if (eDebitCreditType.GetValue() == DebitCreditType.E_Credit)
            {
                qb.AddCompare<int>(PL_JournalEntryDetail.From, 0);
                qb.AddCompare<int>(PL_JournalEntryDetail.To, 0, "!=");
                qb.AddCompare<TaxRegisterType>(PL_JournalEntry.TaxRegister, TaxRegisterType.E_TaxSale);
            }
            else
            {
                qb.AddCompare<int>(PL_JournalEntryDetail.From, 0, "!=");
                qb.AddCompare<int>(PL_JournalEntryDetail.To, 0);
                qb.AddCompare<TaxRegisterType>(PL_JournalEntry.TaxRegister, TaxRegisterType.E_TaxPurchase);
            }


            SqlABConnection conn = GlobalInfo.DBaseInfo.dbManager.NewConnection();
            scc2 = new SqlABCommand(base.providerType, conn);

            QueryBuilder qb2 = new QueryBuilder(true);
            qb2.Clear();
            qb2.AddFunctionAs("SUM({0})", PL_JournalEntryDetail.From);
            qb2.AddFunctionAs("SUM({0})", PL_JournalEntryDetail.To);
            qb2.AddFrom(PL_JournalEntryDetail.Name);
            qb2.AddJoin(QueryBuilder.JoinType.INNER, PL_JournalEntry.JournalNo, PL_JournalEntryDetail.JournalNo);

            pDocNo = new SqlABParameter("@DocNo", PL_JournalEntryDetail.DocumentNo);
            pType = new SqlABParameter("@Type", PL_JournalEntryDetail.Type);
            pCode = new SqlABParameter("@Code", PL_JournalEntryDetail.Code);

            pDate = new SqlABParameter("@Date", PL_JournalEntry.DocumentDate);

            qb2.AddCompare(PL_JournalEntryDetail.DocumentNo, pDocNo);
            qb2.AddCompare(PL_JournalEntryDetail.Type, pType);
            qb2.AddCompare(PL_JournalEntryDetail.Code, pCode);
            qb2.AddCompare(PL_JournalEntry.DocumentDate, pDate, "<=");

            scc2.Parameters.Add(pDocNo);
            scc2.Parameters.Add(pType);
            scc2.Parameters.Add(pCode);
            scc2.Parameters.Add(pDate);

            if (eDebitCreditType.GetValue() == DebitCreditType.E_Credit)
            {
                qb2.AddCompare<int>(PL_JournalEntryDetail.From, 0, "!=");
                qb2.AddCompare<int>(PL_JournalEntryDetail.To, 0);
            }
            else
            {
                qb2.AddCompare<int>(PL_JournalEntryDetail.From, 0);
                qb2.AddCompare<int>(PL_JournalEntryDetail.To, 0, "!=");
            }
            scc2.CommandText = qb2.Query;

            using (SqlABCommand scc = new SqlABCommand(base.providerType, GlobalInfo.SqlConnection))
            {
                scc.CommandText = qb.Query;
                SqlABDataReader dr = scc.ExecuteReader();
                while (dr.Read())
                {
                    Tuple<double, double> returnVal = ElaborateRow(dr);
                    if (eDebitCreditType.GetValue() == DebitCreditType.E_Credit)
                    {
                        if (dr.GetValue<double>(PL_JournalEntryDetail.To) != returnVal.Item1)
                            AddRow(dr, dr.GetValue<double>(PL_JournalEntryDetail.To) - returnVal.Item1);
                    }
                    else
                    {
                        if (dr.GetValue<double>(PL_JournalEntryDetail.From) != returnVal.Item2)
                            AddRow(dr, dr.GetValue<double>(PL_JournalEntryDetail.From) - returnVal.Item2);
                    }
                }
                dr.Close();
            }

            scc2.Dispose();
            return true;
        }

        private Tuple<double, double> ElaborateRow(SqlABDataReader dr)
        {
            pDocNo.Value = dr.GetValue<string>(PL_JournalEntryDetail.DocumentNo);
            pType.Value = dr.GetValue<string>(PL_JournalEntryDetail.Type);
            pCode.Value = dr.GetValue<string>(PL_JournalEntryDetail.Code);
            pDate.Value = ctbFromDate.Today;

            //if (pCode.Value.ToString() == "DALLORTO")
            //    System.Diagnostics.Debug.Write("ECCOCI");

            Tuple<double, double> returnVal = new Tuple<double,double>(0,0);

            SqlABDataReader dr2 = scc2.ExecuteReader();
            if (dr2.Read())
                returnVal = new Tuple<double, double>(dr2.GetValue<double>(PL_JournalEntryDetail.From), dr2.GetValue<double>(PL_JournalEntryDetail.To));

            dr2.Close();

            return returnVal;
        }

        private void AddRow(SqlABDataReader dr, double value)
        {
            if (value < 1)
                return;

            DSDebitCredit.DebitCreditRow dcr = dsDebitCredit.DebitCredit.NewDebitCreditRow();

            drMasters.Find(dr.GetValue<string>(PL_JournalEntry.Type), dr.GetValue<string>(PL_JournalEntry.Code));
            drMasterType.Find(dr.GetValue<string>(PL_JournalEntry.Type));
            
            dcr[PL_JournalEntry.JournalNo.Name] = dr.GetValue<string>(PL_JournalEntry.JournalNo);
            dcr[PL_JournalEntry.Type.Name] = drMasterType.GetValue<string>(PL_MasterType.Description);
            dcr[PL_JournalEntry.Code.Name] = drMasters.GetValue<string>(PL_JournalEntry.Type) == condominium
                                                ? drMasters.GetValue<string>(PL_Masters.Address)
                                                : drMasters.GetValue<string>(PL_Masters.Description);
            dcr[PL_JournalEntry.DocumentNo.Name] = dr.GetString("DocNo");
            dcr[PL_JournalEntry.DocumentDate.Name] = dr.GetValue<string>(PL_JournalEntry.DocumentDate);
            dcr["Amount"] = value;

            dsDebitCredit.DebitCredit.Rows.Add(dcr);
        }

        protected override EmailArgs SendEmail()
        {
            EmailArgs ea = new EmailArgs();
            ea.Subject = Title;
            ea.Attachment = ExportToPdf(Title);
            return ea;
        }

        protected override void OnDoubleClickColumn(string column, string value, CrystalDecisions.Windows.Forms.ObjectInfo[] objectInfo)
        {
            if (column == PL_JournalEntryDetail.JournalNo.Name)
            {
                if (drJournalEntry.Find(value))
                {
                    if (drJournalEntry.GetValue<TaxRegisterType>(PL_JournalEntry.TaxRegister) == TaxRegisterType.E_NORegister)
                    {
                        JournalEntries frm = (JournalEntries)GlobalInfo.OpenForm("Plumber.Plumber.Accounting.Forms.JournalEntries", false);
                        frm.FindRecord(new RadarJournalEntryParam(value));
                    }
                    else
                    {
                        JournalEntriesSalePurchase frm = (JournalEntriesSalePurchase)GlobalInfo.OpenForm("Plumber.Plumber.Accounting.Forms.JournalEntriesSalePurchase", false);
                        frm.FindRecord(new RadarJournalEntryParam(value));
                    }
                }
            }
        }
    }
}